#ifdef ARDUINO

#include <Arduino.h>
#include <cerrno>
#include "Rtos.h"
#include "mcu.h"


#define STDIN_FILENO 0  /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
#define STDERR_FILENO 2 /* standard error file descriptor */

extern "C"
{
/*str 是要输出的字符串。该函数将字符串输出到标准输出流，并自动添加换行符。返回值为输出的字符数，不包括换行符。如果输出失败，则返回 EOF。该函数不支持多线程环境下的线程安全操作。*/
int puts(const char *str) {
    int len = 0;
    for (;;) {
        if (*str == '\0') {
            break;
        } else {
            serial_putchar(*str++);
            len++;
        }
    }
    return len;
}

void _exit(int n) {
    while (1) {
        n = n;
    }
}

int _stat(char *file, struct stat *st) {
    //    debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (0);
}

//int _fstat(int fd, struct stat *st) {
//    if (fd == STDOUT_FILENO) {
//        memset(st, 0, sizeof(*st));
//        st->st_mode = S_IFCHR;
//        st->st_blksize = 1024;
//        return 0;
//    } else {
//        //        debugprintf("Error: _fstat\r\n", 15);
//        return (-1);
//    }
//}

register char *stack_ptr asm("sp");

//caddr_t _sbrk_r(void *reent, size_t incr) {
//    extern char end asm("end"); // Defined by the linker
//    static char *heap_end = NULL;
//    char *prev_heap_end = NULL;
//
//    if (heap_end == NULL)
//        heap_end = &end;
//    prev_heap_end = heap_end;
//
//    if ((heap_end + incr) > stack_ptr) {
//        /* Some of the libstdc++-v3 tests rely upon detecting */
//        /* out of memory errors, so do not abort here. */
//        //	            exit(1);
//        //        debugprintf("_sbrk_r error: heap_end =0x%p , incr =0x%x ,stack_ptr =0x%p\r\n",heap_end,incr,stack_ptr);
//
//        return (caddr_t) -1;
//    }
//
//    heap_end += incr;
//    //   debugprintf("_sbrk_r : heap_end =0x%p , incr =0x%x ,stack_ptr =0x%p\r\n",heap_end,incr,stack_ptr);
//
//    return (caddr_t) prev_heap_end;
//}
//int _write(int file, char *data, int len) {
//    if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) {
//        errno = EBADF;
//        return -1;
//    }
//
//    for (int i = 0; i < len; i++) {
//        serial_putchar(data[i]);
//    }
//
//    // return # of bytes written - as best we can tell
//    return len;
//}


int _gettimeofday(struct timeval *tv, void *tzvp) {
    uint64_t t = Rtos::ticks();            // get uptime in nanoseconds
    tv->tv_sec = t / 1000000000;           // convert to seconds
    tv->tv_usec = (t % 1000000000) / 1000; // get remaining microseconds
    return 0;                              // return non-zero for error
}


int isatty(int fd) {
    //    debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (1);
}

int _lseek(int fd, int ptr, int dir) {
    //   debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (-1);
}

int _open(const char *name, int mode) {
    //    debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (-1);
}

int _close(int fd) {
    //    debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (0);
}


// int _open_r(struct _reent *, const char *, int, int) {
//     logger.error("_open_r");
//     return -1;
// }

int _read(int fd, void *buffer, unsigned int count) {
    //   debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
    return (-1);
}

void _kill() {
    //   debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
}

void _getpid() {
    //   debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
}

//	struct timeval
//	{
//	    long tv_sec;
//	    long tv_usec;
//	};


void _isatty() {
    //    debugprintf("no imp: __FILE__ __LINENO__ _write_r \r\n");
}

void _unlink() {
}
#ifndef SYLIXOS
void utime() {
}
int fchmod(int __fd, mode_t __mode) {
    return -1;
}

int lstat(const char *, struct stat *) { return -1; }
int fchown(int __fildes, uid_t __owner, gid_t __group) {
    return -1;
}
int _open_r(char *path, int flags, ...) {
    /* Pretend like we always fail */
    return -1;
}
#endif
/*ptr 是指向 _reent 结构体的指针，用于支持多线程环境下的线程安全操作。str 是要输出的字符串。该函数将字符串输出到标准输出流，并返回输出的字符数。在输出过程中，该函数会自动添加换行符。*/
int _puts_r(struct _reent *ptr, const char *str) {
    int len = 0;
    for (;;) {
        if (*str == '\0') {
            break;
        } else {
            serial_putchar(*str++);
            len++;
        }
    }
    return len;
}
}
// #endif
#endif
